﻿#pragma warning(disable:4267)
#include <Windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
#include <assert.h>

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd)
{
    wchar_t wszTitle[] = L"B1TextOutput";

    WNDCLASS wcls;
    ZeroMemory(&wcls, sizeof(WNDCLASS));
    wcls.style = CS_HREDRAW | CS_VREDRAW;
    wcls.lpfnWndProc = WindowProc;
    wcls.hInstance = hInstance;
    wcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcls.hIcon = LoadIcon(nullptr, IDI_SHIELD);
    wcls.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcls.lpszClassName = wszTitle;

    if (!RegisterClass(&wcls)) {
        MessageBox(nullptr, L"Register class failed", L"Error", MB_OK);
        return GetLastError();
    }

    // 启动GDI+
    ULONG_PTR gdiplusToken;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);

    HWND hWndMain = CreateWindow(wszTitle, L"B1TextOutput", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
    if (!hWndMain) {
        MessageBox(nullptr, L"Create window failed", L"Error", MB_OK);
        return GetLastError();
    }
    ShowWindow(hWndMain, nShowCmd);
    UpdateWindow(hWndMain);

    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // 关闭GDI+
    Gdiplus::GdiplusShutdown(gdiplusToken);

    return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // 创建宋体字体
    static Gdiplus::Font* pFontSimSun = nullptr;
    static Gdiplus::Font* pFontSimSunBig = nullptr;

    switch (uMsg) {
    case WM_CREATE:
        pFontSimSun = new Gdiplus::Font(L"宋体", 16);
        pFontSimSunBig = new Gdiplus::Font(L"微软雅黑", 36);
        ShowWindow(hWnd, SW_SHOW);
        return 0;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc;

        hdc = BeginPaint(hWnd, &ps);

        // 包装GDI+绘图对象
        Gdiplus::Graphics graphics(hdc);

        // 创建红色画笔
        Gdiplus::Pen penRed(Gdiplus::Color(255, 0, 0));
        // 绘制一个红色的矩形
        graphics.DrawRectangle(&penRed, 0, 0, 200, 120);

        wchar_t wszText[] = L"这是第一行文字";
        wchar_t wszText2[] = L"这是第二行文字,我们需要计算第二行文字显示在什么位置";
        wchar_t wszText3[] = L"这是第三行文字";
        wchar_t wszText4[] = L"上面三行的行高是%d像素";
        wchar_t wszText5[] = L"我的行高是%d像素";

        Gdiplus::SolidBrush brushGreen(Gdiplus::Color(255, 0, 128, 0));
        // 获取字体的高度
        Gdiplus::RectF rect;
        graphics.MeasureString(wszText, -1, pFontSimSun, Gdiplus::PointF(0, 0), &rect);

        // line1
        graphics.DrawString(wszText, -1, pFontSimSun, Gdiplus::PointF(0, 0), &brushGreen);
        // line2
        graphics.DrawString(wszText2, -1, pFontSimSun, Gdiplus::PointF(0, rect.Height), &brushGreen);
        // line3
        graphics.DrawString(wszText3, -1, pFontSimSun, Gdiplus::PointF(0, rect.Height * 2), &brushGreen);
        // line4
        wchar_t wszText4Buffer[256];
        wsprintf(wszText4Buffer, wszText4, (int)rect.Height);
        graphics.DrawString(wszText4Buffer, -1, pFontSimSunBig, Gdiplus::PointF(0, rect.Height * 3), &brushGreen);
        // line5
        Gdiplus::RectF rect2;
        graphics.MeasureString(wszText5, -1, pFontSimSunBig, Gdiplus::PointF(0, 0), &rect2);
        wsprintf(wszText4Buffer, wszText5, (int)rect2.Height);
        graphics.DrawString(wszText4Buffer, -1, pFontSimSunBig, Gdiplus::PointF(0, rect.Height * 3 + rect2.Height), &brushGreen);

        EndPaint(hWnd, &ps);
        return 0;
    }
    case WM_DESTROY:
        delete pFontSimSunBig;
        delete pFontSimSun;
        pFontSimSunBig = nullptr;
        pFontSimSun = nullptr;
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
